/*  This file is part of -_-.

    -_- is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    -_- is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with -_-.  If not, see <http://www.gnu.org/licenses/>.

    Copyright 2012-2013 Oliver Katz */

#ifndef __BUS_SHARE_H
#define __BUS_SHARE_H

#include <stdio.h>
#include "../common/data.h"
#include "ipc.h"

#define Z_SHARE_RW 0
#define Z_SHARE_RO 1

//struct z_share_server: a variable sharing server
typedef struct
{
	z_data **ptrs; //memberof z_share_server: variable references
	int *wp; //memberof z_share_server: whether the variables have write-access
	z_size nptrs; //memberof z_share_server: the number of variable references
	z_ipc_server *srv; //memberof z_share_server: the server
} z_share_server;

z_share_server z_share_server_init(z_ipc_server *ipc, z_size n); //methodof z_share_server: initializer
int z_share_server_release(z_share_server s); //methodof z_share_server: uninitializer
z_data *z_share_server_bind_rw(z_share_server *s, z_size idx, z_data *d); //methodof z_share_server: bind a variable (read/write)
//returnof z_share_server_bind_rw: z_data *: NULL on error
z_data *z_share_server_bind_ro(z_share_server *s, z_size idx, z_data *d); //methodof z_share_server: bind a variable (read-only)
//returnof z_share_server_bind_ro: z_data *: NULL on error
int z_share_server_serve(z_share_server *s); //methodof z_share_server: run server

//struct z_share_client: a variable sharing client (to connect to a z_share_server)
typedef struct
{
	z_ipc_client *cli; //memberof z_share_client: the interprocess-communication client
} z_share_client;

z_share_client z_share_client_init(z_ipc_client *ipc); //memberof z_share_client: initializer
int z_share_client_release(z_share_client c); //memberof z_share_client: uninitializer
z_data z_share_client_pull(z_share_client *c, z_size idx); //memberof z_share_client: pull a variable from the server
z_data z_share_client_push(z_share_client *c, z_size idx, z_data *d); //memberof z_share_client: push a variable to the server (only works if write access is enabled for that variable)

/// Shares exist to share variables between processses. You can share variables as follows. Here's an example server:
/// {{z_data variable = z_data_init(0, 0);
/// z_ipc_server server = z_ipc_server_init_global(8950);
/// z_ipc_server_connect(&server);
/// z_share_server share = z_share_server_init(&server, 1);
/// z_share_server_bind_rw(&share, 0, &variable);
/// z_share_server_serve(&share);}}
/// 
/// And the client that accesses 'variable':
/// {{z_ipc_client client = z_ipc_client_init_global("127.0.0.1", 8950);
/// z_ipc_client_connect(&client);
/// z_share_client share = z_share_client_init(&client);
/// z_data variable = z_share_client_pull(&share, 0);}}

#endif
